home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / button12.lha / pathtext.ps < prev    next >
Text File  |  1993-08-05  |  9KB  |  192 lines

  1. %!
  2. % Cookbook Example Program from First Printing, Revised 7 Jan 1985
  3. % Program: Placing Text Along an Arbitrary Path     Number: 17
  4. %-----------------------------------------------------------------------------
  5. %
  6. /pathtextdict 26 dict def                   % Local storage for the procedure
  7.                         % ``pathtext.''
  8.                                
  9. /pathtext                                   % ``pathtext'' will place a string
  10.   { pathtextdict begin                      % of text along any path. It takes
  11.     /offset exch def                        % a string and starting offset
  12.     /str exch def                           % distance from the beginning of
  13.                         % the path as its arguments. Note
  14.                         % that ``pathtext'' assumes that a
  15.                         % path has already been defined
  16.                         % and after it places the text
  17.                         % along the path, it clears the
  18.                         % current path like the ``stroke''
  19.                         % and ``fill'' operators; it also
  20.                         % assumes that a font has been
  21.                         % set. ``pathtext'' begins placing
  22.                         % the characters along the current
  23.                         % path, starting at the offset
  24.                         % distance and continuing until
  25.                         % either the path length is
  26.                         % exhausted or the entire string
  27.                         % has been printed, whichever
  28.                         % occurs first. The results will
  29.                         % be more effective when a small
  30.                         % point size font is used with
  31.                         % sharp curves in the path.
  32.                                        
  33.     /pathdist 0 def                         % Initialize the distance we have
  34.                         % travelled along the path.
  35.     /setdist offset def                     % Initialize the distance we have
  36.                         % covered by setting characters.
  37.     /charcount 0 def                        % Initialize the character count.
  38.     gsave
  39.       flattenpath                           % Reduce the path to a series of
  40.                         % straight line segments. The
  41.                         % characters will be placed along
  42.                         % the line segments in the
  43.                         % ``linetoproc.''
  44.       {movetoproc} {linetoproc}             % The basic strategy is to process
  45.     {curvetoproc} {closepathproc}       % the segments of the path,
  46.     pathforall                          % keeping a running total of the
  47.                         % distance we have travelled so
  48.                         % far (pathdist). We also keep
  49.                         % track of the distance taken up
  50.                         % by the characters that have been
  51.                         % set so far (setdist). When the
  52.                         % distance we have travelled along
  53.                         % the path is greater than the
  54.                         % distance taken up by the set
  55.                         % characters, we are ready to set
  56.                         % the next character (if there are
  57.                         % any left to be set). This
  58.                         % process continues until we have
  59.                         % exhausted the full length of the
  60.                         % path.
  61.     grestore
  62.     newpath                                 % Clear the current path.
  63.     end
  64.   } def
  65.        
  66. pathtextdict begin
  67. /movetoproc                                 % ``movetoproc'' is executed when
  68.   { /newy exch def /newx exch def           % a moveto component has been
  69.                         % encountered in the pathforall
  70.                         % operation.
  71.     /firstx newx def /firsty newy def       % Remember the ``first point'' in
  72.                         % the path so that when we get a
  73.                         % ``closepath'' component we can
  74.                         % properly handle the text.
  75.     /ovr 0 def
  76.     newx newy transform
  77.     /cpy exch def /cpx exch def             % Explicitly keep track of the
  78.                         % current position in device
  79.                         % space.
  80.   } def
  81.        
  82. /linetoproc                                 % ``linetoproc'' is executed when
  83.                         % a lineto component has been
  84.                         % encountered in the pathforall
  85.                         % operation.
  86.   { /oldx newx def /oldy newy def           % Update the old point.
  87.     /newy exch def /newx exch def           % Get the new point.
  88.     /dx newx oldx sub def
  89.     /dy newy oldy sub def
  90.     /dist dx dup mul dy dup mul add         % Calculate the distance between
  91.                         % the old and the new point.
  92.       sqrt def
  93.     /dsx dx dist div ovr mul def            % dsx and dsy are used to update
  94.     /dsy dy dist div ovr mul def            % the current position to be just
  95.                         % beyond the width of the previous
  96.                         % character.
  97.     oldx dsx add oldy dsy add transform
  98.     /cpy exch def /cpx exch def             % Update the current position.
  99.     /pathdist pathdist dist add def         % Increment the distance we have
  100.                         % travelled along the path.
  101.     { setdist pathdist le                   % Keep setting characters along
  102.                         % this path segment until we have
  103.                         % exhausted its length.
  104.     { charcount str length lt           % As long as there are still
  105.         {setchar} {exit} ifelse }       % characters left in the string,
  106.                         % set them.
  107.     { /ovr setdist pathdist sub def     % Keep track of how much we have
  108.       exit }                            % overshot the path segment by
  109.     ifelse                              % setting the previous character.
  110.                         % This enables us to position the
  111.                         % origin of the following
  112.                         % characters properly on the path.
  113.     } loop
  114.   } def
  115.        
  116. /curvetoproc                                % ``curvetoproc'' is executed when
  117.   { (ERROR: No curveto's after flattenpath!)% a curveto component has been
  118.     print                                   % encountered in the pathforall
  119.   } def                                     % operation. It prints an error
  120.                         % message since there shouldn't be
  121.                         % any curveto's in a path after
  122.                         % the flattenpath operator has
  123.                         % been executed.
  124.                                 
  125. /closepathproc                              % ``closepathproc'' is executed
  126.   { firstx firsty linetoproc                % when a closepath component has
  127.     firstx firsty movetoproc                % been encountered in the
  128.   } def                                     % pathforall operation. It
  129.                         % simulates the action of the
  130.                         % operator ``closepath'' by
  131.                         % executing ``linetoproc'' with
  132.                         % the coordinates of the most
  133.                         % recent ``moveto'' and then
  134.                         % executing ``movetoproc'' to the
  135.                         % same point.
  136.                              
  137. /setchar                                    % ``setchar'' sets the next
  138.   { /char str charcount 1 getinterval def   % character in the string along
  139.                         % the path and then updates the
  140.                         % amount of path we have
  141.                         % exhausted.
  142.     /charcount charcount 1 add def          % Increment the character count.
  143.     /charwidth char stringwidth pop def     % Find the width of the character.
  144.     gsave
  145.       cpx cpy itransform translate          % Translate to the current
  146.                         % position in user space.
  147.       dy dx atan rotate                     % Rotate the x-axis to coincide
  148.                         % with the current segment.
  149.       0 0 moveto char show
  150.       currentpoint transform
  151.       /cpy exch def /cpx exch def           % Update the current position
  152.     grestore                                % before we restore ourselves to
  153.                         % the untransformed state.
  154.     /setdist setdist charwidth add def      % Increment the distance we have
  155.   } def                                     % covered by setting characters.
  156. end
  157.    
  158. % Don't need to print out this example for use as a library:
  159. %/Helvetica findfont 11.5 scalefont setfont  % Set up the font we wish to use.
  160. %                                         
  161. %newpath                                     % Define the path along which we
  162. %                        % wish to place the text.
  163. %  200 500 50 0 270 arc
  164. %  200 80 add 500 50 270 180 arc
  165. %                   
  166. %(If my film makes one more person feel\
  167. % miserable I'll feel I've done my job.\
  168. % -- WOODY ALLEN) 40 pathtext                % Print the string along the path
  169. %                        % at an offset of 40 points.
  170. %                                    
  171. %newpath                                     % Draw an outline shape suggestive
  172. %                        % of a movie camera.
  173. %  165 360 moveto 315 360 lineto             % Draw the box part.
  174. %  315 430 lineto 165 430 lineto
  175. %  closepath
  176. %  315 390 moveto 355 375 lineto             % Draw the lens part.
  177. %  355 415 lineto 315 400 lineto
  178. %1.5 setlinewidth stroke
  179. %               
  180. %                        % A PROBLEM FOR THE READER: This
  181. %                        % algorithm places characters
  182. %                        % along the path according to the
  183. %                        % origin of each character.
  184. %                        % Rewrite the algorithm so that
  185. %                        % the characters are placed
  186. %                        % according to the center of their
  187. %                        % width. This will yield better
  188. %                        % results around sharp curves and
  189. %                        % when larger point sizes are
  190. %                        % used.
  191. %showpage
  192.